在 django 專案中我們會把設定都寫在 settings.py
內,包含了 SECRET_KEY
等機密資訊,通常專案都會做版本控制上 git,但把這些機密資訊也上 git 是很不好的一件事,畢竟 github 也是曾經被駭過的,所以最好是把這些不想讓別人知道的資訊寫在另外一個檔案內然後要用的時候再 import 進來,再來就是專案如果要部署在多台 server,每個 server 的設定都不一樣,所以我覺得每一台 server 要不一樣的設定檔不上 git 會比較好
我的做法是另外寫一個 env.json
去記錄,然後不要上 git,但是還是要告訴別人這個專案要寫一個 env.json
,所以另外還會再寫一個示範檔案 env.json.default
告訴別人裡面該寫什麼,這個 env.json.default
就會上 git
內容如下
{
"debug":false,
"SECRET_KEY":"your_django_SECRET_KEY",
"DB_HOST":"192.168.0.1:27017,192.168.0.2:27017,192.168.0.2:27017",
"DB_ROOT_USER":"DB_ROOT_USER",
"DB_ROOT_PASSWORD":"DB_ROOT_PASSWORD",
"allow_host":["127.0.0.1",".localhost"]
}
debug
是 true
,在正式部署時要設定為 false
,不然別人可以透過輸入 api 看到 debug 以及專案上的資訊["*",]
,很多教學為了方便起見都會教你這樣設定讓你架在哪都行,但這樣駭客對你發出請求,也是隨便從哪裡都可以。設定 allow_host 只包含你想架在哪個 ip 或 domain 就好,注意如果要設定允許架在哪個 domain,寫法要像 .back-end-domain
,域名前面要在加個 .
,這是 django 的寫法回到 settings.py
,在最上面加入
import json
env = json.load(open('./back_end/env.json'))
DB_HOST = env['DB_HOST']
DB_ROOT_USER = env['DB_ROOT_USER']
DB_ROOT_PASSWORD = env['DB_ROOT_PASSWORD']
其他設定
SECRET_KEY = env['SECRET_KEY']
...
DEBUG = env['debug']
...
ALLOWED_HOSTS = env['allow_host']
之後在 views.py
內連接 db 會像這樣
from django.conf import settings
db_host = settings.DB_HOST
db_root_user = settings.DB_ROOT_USER
db_root_password = settings.DB_ROOT_PASSWORD
...
def func1(request):
myclient = pymongo.MongoClient(
'mongodb://'+db_root_user+':'+db_root_password+'@'+db_host+'+'/?authSource=admin')
部署一個後端 service 和部署前端網站的方式不太一樣,前端架站很簡單,基本上就是架站工具 + web bundle 就結束了,如下圖
而部署後端服務需要在架站工具和 application 之間建立一個 Web Server Gateway Interface (WSGI),如下圖
python 後端這邊最常用來實作 WSGI 應該就是 uWSGI,直接用 pip 安裝
pip install uwsgi
來創建一個 uWSGI 的設定檔,名稱叫什麼都可以,副檔名是 ini
就好,放在哪也都可以,我的話都是放在後端專案底下
[uwsgi]
socket = 127.0.0.1:8000
chdir = /path-to-your-backend-project
module = back_end.wsgi
home = /path-to-your-python-virtual-environment
wsgi.py
,這個就是來串 WSGI 的,架設你的專案叫 back_end
,那就設定 module = back_end.wsgi
再來把 WSGI 跑起來
uwsgi --ini /path-to-yourfile.ini
講完 WSGI ,我想講一下 ASGI,ASGI 全名是 Asynchronous Server Gateway Interface,可以想像是 WSGI 的升級版,WSGI 是比較舊的東西,並不支持一些新的網路協定和技術,所以為了支持新的網路技術,有了 ASGI 出現,但這我也還在研究中,不過 WSGI 在 web2.0 的使用中已經足夠好了,大部分的 python 後端也是用 WSGI,用到 ASGI 還是比較少的
在串後端和 WSGI 前,想先介紹 virtual host 這個技術,我們在架網站的時候,都會架在 80 port 或是 443 port,也就是 http port 和 https port,可是一台 server 只有一個 80 或 443 port 啊,那我想部署多個專案再同台 server 的 80 或 443 port 怎麼辦呢?這個時候就要用到 virtual host 這個技術啦!
我們先在 nginx 目錄下新增 sites-available
和 sites-enabled
兩個資料夾,然後在 sites-available
新增一個文件,比方說你有個網站要架在 blog.mydomain.com
,那就新增一個文件叫 blog.mydomain.com
,裡面的內容就是這個網站的設定,所以我們會有很多個網站的設定寫在個別的文件,然後如果要使用這個網站,就做個連結放到 sites-enabled
內
再來要改 nginx.conf
中 http
部分的內容,原本裡面是長得像這樣
http {
...
server {
listen 80;
server_name your_domain_name;
return 301 https://your_domain_name;
}
server{
listen 443 ssl http2;
server_name your_domain_name;
ssl_certificate /etc/letsencrypt/live/your_domain_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain_name/privkey.pem;
location / {
root path_of_web_bundle;
index index.html index.htm;
}
}
include servers/*;
}
現在改成這樣
http {
...
include sites-enabled/*;
}
引入 sites-enabled
中所有的網站設定
好啦,WSGI 架起來後,在 sites-available
內新增一個後端網站的設定檔,內容如下
server{
listen 80;
server_name back-end.mydomain.com;
return 301 https://back-end.mydomain.com;
}
server{
listen 443 ssl;
server_name back-end.mydomain.com;
ssl_certificate /etc/letsencrypt/live/back-end.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/back-end.mydomain.com/privkey.pem;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
}
主要是 location /
裡面的設定有區別,我們需要 include uwsgi 的參數,這個東西 nginx 預設已經有幫你寫好了,不用改,再來就是 uwsgi_pass
要設定你剛剛把 uWSGI 架在哪裡,然後把這個設定做個連結到 sites-enabled
內,再 reload 一下 nginx 就大功告成囉!